﻿using jvm.classfile.constantpool;
using jvm.rtda.heap.clazz.method;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace jvm.rtda.heap.clazz.cp
{
    class InterfaceMethodRef : MemberRef
    {
        private JMethod method; // 指针缓存

        public InterfaceMethodRef(JConstantPool cp, ConstantMemberrefInfo memberrefInfo) : base(cp, memberrefInfo)
        {
        }

        public JMethod ResolvedInterfaceMethod()
        {
            if (method == null)
            {
                ResolveInterfaceMethodRef();
            }
            return method;
        }

        void ResolveInterfaceMethodRef()
        {
            JClass d = pool.jClass;
            JClass c = ResolvedClass();
            if (!c.Is(AccessFlags.ACC_INTERFACE))
            {
                Console.WriteLine("java.lang.IncompatibleClassChangeError");
                Environment.Exit(0);
            }
            JMethod method = LookupInterfaceMethod(c, name, descriptor);
            if (method == null)
            {
                Console.WriteLine("java.lang.NoSuchMethodError");
                Environment.Exit(0);
            }
            if (!method.IsAccessibleTo(d))
            {
                Console.WriteLine("java.lang.IllegalAccessError");
                Environment.Exit(0);
            }
            this.method = method;
        }

        JMethod LookupInterfaceMethod(JClass iface, string name, string descriptor)
        {
            foreach (JMethod method in iface.methods)
            {
                if (method.name.Equals(name) && method.descriptor.Equals(descriptor))
                {
                    return method;
                }
            }
            return MethodLookUp.LookUpMethodInInterfaces(iface.interfaces, name, descriptor);
        }
    }
}
